//#include "stdafx.h"

#include "ServerMixer.h"
#include <stdlib.h>
#include <memory.h>

CServerMixer::CServerMixer()
	: pltbuf(NULL)
	, prtbuf(NULL)
{
}

CServerMixer::~CServerMixer()
{
	ClearBuf();
}

void CServerMixer::ClearBuf()
{
	if(pltbuf)
	{
		for (int i=0;i<nInChnls;++i)
		{
			delete[] pltbuf[i];
		}
		delete[] pltbuf;
		pltbuf=NULL;
	}
	if(prtbuf)
	{
		for (int i=0;i<nInChnls;++i)
		{
			delete[] prtbuf[i];
		}
		delete[] prtbuf;
		prtbuf=NULL;
	}
}

void CServerMixer::ReallocBuf(int nChnls)
{
	ClearBuf();
	if(nChnls>0)
	{
		pltbuf = new float*[nChnls];
		prtbuf = new float*[nChnls];
		for (int i=0;i<nChnls;++i)
		{
			pltbuf[i]=new float[nSmpls];
			prtbuf[i]=new float[nSmpls];
		}
	}
}

int CServerMixer::SetInputChannels(CChannelForMixer** pChnlPtrArray,int n)
{
	ReallocBuf(n);
	return CMixer::SetInputChannels(pChnlPtrArray,n);
}

int CServerMixer::SetBufferSize(int nSamples)
{
	int n=CMixer::SetBufferSize(nSamples);
	ReallocBuf(nInChnls);
	return n;
}

int CServerMixer::Process(void)
{
	//Input and mix
	size_t sz=nSmpls*sizeof(float);
	float *ptl=NULL,*ptr=NULL;
	memset(plobuf,0,sz);
	memset(probuf,0,sz);
	int i=0,j=0;
	int processed_samples=0;
	for(i=0;i<nInChnls;++i)
	{
		if(pIcs[i]->IsPassBy)
			continue;
		ptl=pltbuf[i];
		ptr=prtbuf[i];
		memset(plibuf,0,sz);
		memset(pribuf,0,sz);
		memset(ptl,0,sz);
		memset(ptr,0,sz);
		if(pIcs[i]->ProcessData(plibuf,pribuf,nSmpls)>0)
		{
			processed_samples=nSmpls;
			for(j=0;j<nSmpls;++j)
			{
				ptl[j]=plibuf[j];
				ptr[j]=pribuf[j];
				plobuf[j]+=plibuf[j];//mix left
				probuf[j]+=pribuf[j];//mix right
			}
		}
	}
	if (processed_samples<=0)
	{//No sample input...
		return 0;
	}
	//Output
	float m=0.5f;
	int nO=nInChnls>nOutChnls?nOutChnls:nInChnls;
	for (i=0;i<nO;++i)
	{
		if(pOcs[i]->IsPassBy)
			continue;
		ptl=pltbuf[i];
		ptr=prtbuf[i];
		for(j=0;j<nSmpls;++j)
		{
			ptl[j]=(plobuf[j]-ptl[j])*m;//diminish the income talking peer's left
			ptr[j]=(probuf[j]-ptr[j])*m;//diminish the income talking peer's right
		}
		pOcs[i]->ProcessData(ptl,ptr,nSmpls);
	}
	for(j=0;j<nSmpls;++j)
	{
		plobuf[j]*=m;
		probuf[j]*=m;
	}
	for(i=nO;i<nOutChnls;++i)
	{
		if(!pOcs[i]->IsPassBy)
		{
			pOcs[i]->ProcessData(plobuf,probuf,nSmpls);
		}
	}
	return nSmpls;
}